 
 --TS2 swep base modded for Epidemic
 
 if ( SERVER ) then 
   
 	AddCSLuaFile( "shared.lua" ) 

 end 

   
 SWEP.Spawnable			= false 
 SWEP.AdminSpawnable		= false 
 
 SWEP.HolsteredAtStart = true;
 
 SWEP.HealthAmt = 100;
 SWEP.Degrades = true;
 SWEP.DegradeAmt = 0; --Degrade amount is the amount it degrades health by every 15 bullets.
 SWEP.BulletsShotSinceLastDegrade = 0;
 
 --Jams only occur when gun health is at <30%
 SWEP.Jams = true;
 SWEP.JamChance = 0; --Jam chance is any number from 0-100.  The higher the number, the higher the chance it jams.
 SWEP.BulletsShotBeforeJam = 0; --Amount of bullets to shoot before it randomly decides if the gun should jam.
 SWEP.BulletsShotSinceLastJamChance = 0;
 SWEP.BulletsToJam = 0;
 
 SWEP.Primary.CanToggleHolster = true;
 
SWEP.Primary.PositionPosOffset = Vector( 0, 0, 0 );
SWEP.Primary.PositionAngleOffset = Angle( 0, 0, 0 );
SWEP.Primary.PositionOffsetSet = false;

 SWEP.Primary.Sound			= Sound( "Weapon_AK47.Single" ) 
 SWEP.Primary.Damage			= 40 
 SWEP.Primary.NumShots		= 1 
 SWEP.Primary.Cone			= 0.02 
 SWEP.Primary.Delay			= 0.15 
 SWEP.Primary.Tracer = "Tracer";
 SWEP.Primary.ReloadDelay = 1.5;
 
 SWEP.Primary.Recoil			= .2 
 SWEP.Primary.RecoilAdd			= .1
 SWEP.Primary.RecoilMin = .2
 SWEP.Primary.RecoilMax = .6
 SWEP.Primary.RecoverTime = 1;
 
 SWEP.Primary.SpreadCone = Vector( .05, .05, .05 );
   
SWEP.Primary.ReloadingAmount = 0;
SWEP.Primary.CurrentAmmo = 0;
SWEP.Primary.CurrentClip = 0;
 SWEP.Primary.Automatic		= false 
 SWEP.Primary.Ammo			= "none" 

 SWEP.Primary.ViewPunchMul = 1;
 
 SWEP.NextPrimaryAttack = 0;

 SWEP.Slot = 2;
 
 SWEP.Melee = false;
 SWEP.Charging = false;
 SWEP.ChargeTimeStart = 0;
 SWEP.ChargeTimeMax = 0;
   
 /*--------------------------------------------------------- 
 ---------------------------------------------------------*/ 
 function SWEP:Initialize() 
   
 	if ( SERVER ) then 
 		self:SetWeaponHoldType( self.HoldType );
 	end
 	
 	
 	 
 end 
 
 function SWEP:GetWeaponHoldType()
 
 	return self.EpiHoldType;
 
 end
   
 function SWEP:Deploy()
 
 	--self.Owner:CrosshairDisable(); 
 
 end
 
 function SWEP:GetMeleePowerPerc()
 
  	local t1 = CurTime() - self.ChargeTimeStart;
 	local t2 = self.ChargeTimeMax - self.ChargeTimeStart;
 	return math.Clamp( t1 / t2, 0, 1 );
 
 end
 
 function SWEP:MeleeStrike( perc )
 
	local powerperc = perc;
	
	if( not perc ) then
		powerperc = 1 + self:GetMeleePowerPerc();
	end
	
	self.Weapon:SendWeaponAnim( ACT_VM_HITCENTER );
	self.NextPrimaryAttack = CurTime() + math.Rand( .4, .6 );
	
	self.Weapon:EmitSound( self.SwingSounds[math.random( 1, #self.SwingSounds)] );

	self.ChargeTimeStart = CurTime();
	self.ChargeTimeMax = CurTime() + 1;
	
	if( SERVER ) then
	
		local trace = { }
		trace.start = self.Owner:EyePos();
		trace.endpos = trace.start + self.Owner:GetAimVector() * 50;
		trace.filter = self.Owner;
	
		local tr = util.TraceLine( trace );
		
		if( tr.Entity and tr.Entity:IsValid() ) then
		
			local norm = ( self.Owner:EyePos() - tr.HitPos ):Normalize();
		
			tr.Entity:EmitSound( "weapons/crossbow/hitbod2.wav", 100, 170 );
		
			if( not tr.Entity:IsPlayer() ) then
				tr.Entity:GetPhysicsObject():ApplyForceOffset( norm * -9000 * math.Clamp( powerperc, .4, 1 ), tr.HitPos );
			else
				local push = -80 * norm * powerperc;
				tr.Entity:SetVelocity( push );
				HandleMeleeDamage( tr.Entity, self.Primary.Damage, self.Primary.Damage );
			end
			
		end
		
	end

 end
   
 function SWEP:Think() 
   
 	if ( self.Weapon:GetNetworkedBool( "reloading", false ) and self.ShotgunReload ) then 
 	 
 		if ( self.Weapon:GetVar( "reloadtimer", 0 ) < CurTime() ) then 
 			 
 			// Finsished reload - 
 			if ( self.Primary.ReloadingAmount <= 0 ) then 
 				self.Weapon:SetNetworkedBool( "reloading", false ) 
 				return 
 			end 
 			 
 			// Next cycle 
 			self.Weapon:SetVar( "reloadtimer", CurTime() + 0.3 ) 
 			self.Weapon:SendWeaponAnim( ACT_VM_RELOAD ) 
 			
 			self.Primary.ReloadingAmount = self.Primary.ReloadingAmount - 1;
 			 
 			// Finish filling, final pump 
 			if ( self.Primary.ReloadingAmount <= 0 ) then 
 				self.Weapon:SendWeaponAnim( ACT_SHOTGUN_RELOAD_FINISH ) 
 					 
		 		if( self.ReloadCB ) then
		 		
		 			--self.Primary.CurrentClip = self.Primary.CurrentClip - self.Primary.OriReloadingAmount;
		 			self.ReloadCB();
		 		
		 		end

 			else 
 			 
 			end 
 			 
 		end 
 	 
 	end 
   
 end  
 
 function SWEP:OnReload() 
 
 
 	if ( self.Weapon:GetNetworkedBool( "reloading", false ) ) then return end
	 
	 if( self.Primary.CurrentClip == self.Primary.MaxAmmoClip ) then
	 
	 	return;
	 
	 end
	 
	self.Weapon:SetNetworkedBool( "reloading", true );
	 
 	if( self.ShotgunReload ) then

		if ( self.Primary.CurrentClip < self.Primary.MaxAmmoClip && self.Primary.ReloadingAmount > 0 ) then
			
			self.Weapon:SetVar( "reloadtimer", CurTime() + 0.3 );
			self.Weapon:SendWeaponAnim( ACT_VM_RELOAD );
			
		end
 	
 	else
 	
	 	local function reload()
	 
	 		if( self.ReloadCB ) then
	 		
	 			self.ReloadCB();
	 		
	 		end
	 
		 	self.Weapon:SetNetworkedBool( "reloading", false );
		 	
		end
		timer.Simple( self.Primary.ReloadDelay, reload );

 		self.Weapon:SendWeaponAnim( ACT_VM_RELOAD );

	end
 
 end
 
 function SWEP:Reload() 


 end 

 
 function SWEP:SecondaryAttack() 

	
 end 
 
  SWEP.Primary.LastShot = 0;
  
  SWEP.Primary.NextEmptyClick = 0;
   
 function SWEP:PrimaryAttack() 

   self.Primary.PositionChange = CurTime();
   
   if ( self.Weapon:GetNetworkedBool( "reloading", false ) ) then return end

   	if( CurTime() < self.NextPrimaryAttack ) then
   	
   		return;
   	
   	end

	if( ( SERVER and self.Owner:GetPlayerHolstered() ) or
		( CLIENT and ClientVars["Holstered"] ) ) then
		
		return;
		
	end
	
	if( self.Melee ) then
	
		local mul = 0;
	
		if( self.ChargeTimeStart > 0 ) then
		
			mul = nil;
		
		else
		
			mul = math.Rand( .8, 1.2 );
		
		end
	
		self:MeleeStrike( mul );
		return;
	
	end
   
	if( self.Primary.CurrentClip <= 0 ) then
		if( self.Primary.NextEmptyClick < CurTime() ) then
			self.Weapon:EmitSound( Sound( "Weapon_Pistol.Empty" ) );
			--self:Reload();
			self.Primary.NextEmptyClick = CurTime() + .4;
		end
		return; 
	end
   	
   	local vel = self.Owner:GetVelocity():Length();

	if( vel > 120 ) then

		if( self.Owner:KeyDown( IN_WALK ) ) then
		
			return;
		
		end
   		
   	end
   	
   	if( SERVER ) then
   	
	   	if( self.Jams and self.HealthAmt <= 30 and not self.Jammed ) then
	   	
	   		if( self.BulletsShotSinceLastJamChance >= self.BulletsShotBeforeJam ) then
	   		
	   			self.BulletsShotBeforeJam = math.Clamp( 1, 5 );
	   			self.BulletsShotSinceLastJamChance = 0;
	   			
	   			--Genius jam deciding algorithm right here.
	   			if( math.random( 1, 100 ) <= self.JamChance ) then
	   			
	   				self.Jammed = true;
	   				
	   				umsg.Start( "JW" );
	   				umsg.End();
	   		
	   			end
	   		
	   		end
	   	
	   	end
	   	
	end
   	
   	if( not self.Jammed ) then
   	
	   	local recov = math.Clamp( ( CurTime() - self.Primary.LastShot ) / self.Primary.RecoverTime, 0, 1 );
	    recov = 1 - recov;
	    
	   	self.Primary.Recoil = math.Clamp( self.Primary.Recoil * recov, self.Primary.RecoilMin, self.Primary.RecoilMax );
	   
	 	self:ShootBullets();
 	 
 	 end
 	 
 	self.NextPrimaryAttack = CurTime() + self.Primary.Delay;
 	 
 end 
   
   
function SWEP:ShootBullets()

	local mul = 1;

 	if( self.Owner:KeyDown( IN_SPEED ) and self.Owner:GetVelocity():Length() > 110 ) then
 		mul = 5;
 	elseif( self.Owner:GetVelocity():Length() > 40 ) then
		mul = 2;
	end
	
	if( self.Owner:KeyDown( IN_ATTACK2 ) ) then
	
		mul = mul * .7;
	
	end
	
	local recoiladd = 0;
	local rdmg, ldmg;
	
	if( SERVER ) then
	
		rdmg = math.Clamp( 60 - self.Owner:GetPlayerRArmHP(), 0, 60 );
		ldmg = math.Clamp( 60 - self.Owner:GetPlayerLArmHP(), 0, 60 );
	
	else

		rdmg = math.Clamp( 60 - ClientVars["RArmHP"], 0, 60 );
		ldmg = math.Clamp( 60 - ClientVars["LArmHP"], 0, 60 );
	
	
	end
	
	local dmg = rdmg + ldmg;
	
	recoiladd = 2 * ( dmg / 40 );
	
	 local bullet = {} 
 	bullet.Num 		= self.Primary.NumShots;
 	bullet.Src 		= self.Owner:GetShootPos()			// Source 
 	bullet.Dir 		= self.Owner:GetAimVector()			// Dir of bullet 
 	bullet.Spread 	= ( self.Primary.SpreadCone + Vector( .04, .04, .04 ) * ( self.Primary.Recoil + recoiladd ) ) * mul;
 	bullet.Tracer	= 1									// Show a tracer on every x bullets  
 	bullet.Force	= .1									// Amount of force to give to phys objects 
 	bullet.Damage	= self.Primary.Damage;
 	bullet.TracerName = self.Primary.Tracer;

	self.Primary.CurrentAmmo = self.Primary.CurrentAmmo - 1;
 	self.Primary.CurrentClip = self.Primary.CurrentClip - 1;
 	 
 	self.Owner:FireBullets( bullet ) 
 	self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK ) 		// View model animation 
 	self.Owner:MuzzleFlash()								// Crappy muzzle light 
 	self.Owner:SetAnimation( PLAYER_ATTACK1 )
 	
 	self.Weapon:EmitSound( self.Primary.Sound, 300 );
 	
 	self.Primary.Recoil = math.Clamp( self.Primary.Recoil + self.Primary.RecoilAdd, self.Primary.RecoilMin, self.Primary.RecoilMax );
 	
	self:ApplyRecoil( recoiladd );
	
	if( self.Degrades ) then
	
		self.BulletsShotSinceLastDegrade = self.BulletsShotSinceLastDegrade + 1;
		
		if( self.BulletsShotSinceLastDegrade >= 15 ) then
		
			self.BulletsShotSinceLastDegrade = 0;
		
			self.HealthAmt = math.Clamp( self.HealthAmt - self.DegradeAmt, 0, 100 );
		
		end
		
	end
	
   	if( self.Jams ) then
   	
   		self.BulletsShotSinceLastJamChance = self.BulletsShotSinceLastJamChance + 1;
   	
   	end

end

function SWEP:ApplyRecoil( add )

 	local eyeang = Angle( ( self.Primary.Recoil + add ) * math.Rand( -1, .3 ),
 						  ( self.Primary.Recoil + add ) * math.Rand( -.7, .7 ), 0 );
 
 	if( self.Owner:KeyDown( IN_SPEED ) and self.Owner:GetVelocity():Length() > 110 ) then
 		eyeang = eyeang * 4;
 	 elseif( self.Owner:GetVelocity():Length() > 40 ) then
		eyeang = eyeang * 2;
	end
	
	self.Owner:ViewPunch( eyeang * self.Primary.ViewPunchMul );
 
	if( SERVER and not self.Owner:IsListenServerHost() ) then return; end
 
 	self.Owner:SetEyeAngles( eyeang + self.Owner:EyeAngles() ); 
 	 
 	

end

SWEP.Primary.PositionMode = 2;
SWEP.Primary.PositionTime = .2;
SWEP.Primary.PositionMul = 1;
SWEP.Primary.GoToOriginalPosition = false;
SWEP.Primary.NextPositionMode = 0;
SWEP.Primary.OldPositionMode = 0;

function SWEP:GoIntoPosition( pos, ang, newpos, newang )

	local mul = self.Primary.PositionMul;

	if( newang ) then
	
		ang:RotateAroundAxis( ang:Right(), mul * newang.x );
		ang:RotateAroundAxis( ang:Up(), mul * newang.y );
		ang:RotateAroundAxis( ang:Forward(), mul * newang.z );
	
	end
	
	pos = pos + newpos.x * ang:Right() * mul;
	pos = pos + newpos.y * ang:Up() * mul;
	pos = pos + newpos.z * ang:Forward() * mul;

	return pos, ang;

end

 function SWEP:GetViewModelPosition( pos, ang ) 
	
	if( self.Primary.OldPositionMode == 0 or self.Primary.PositionMul == 1 ) then
	
		self.Primary.OldPositionMode = self.Primary.PositionMode;
	
	end
	
	if( self.Primary.PositionMode == 1 ) then --Going into iron sights
		if( self.Primary.IronSightPos ) then
 			pos, ang = self:GoIntoPosition( pos * 1, ang * 1, self.Primary.IronSightPos + self.Primary.PositionPosOffset, ( self.Primary.IronSightAng or Vector( 0, 0, 0 ) ) + self.Primary.PositionAngleOffset );
 	 	end
 	 elseif( self.Primary.PositionMode == 2 ) then --Going holstered/unholstered
 	 	if( self.Primary.HolsteredPos ) then
 			pos, ang = self:GoIntoPosition( pos * 1, ang * 1, self.Primary.HolsteredPos, self.Primary.HolsteredAng or Vector( 0, 0, 0 ) );
 	 	end
 	 elseif( self.Primary.PositionMode == 3 ) then --Charge
 	 	if( self.Primary.ChargedPos ) then
 			pos, ang = self:GoIntoPosition( pos * 1, ang * 1, self.Primary.ChargedPos, self.Primary.ChargedAng or Vector( 0, 0, 0 ) );
 	 	end 	 
 	 end
 	 
 	 if( self.Primary.GoToOriginalPosition ) then
	 	
	 	self.Primary.PositionMul = math.Clamp( self.Primary.PositionMul - ( 1 / self.Primary.PositionTime ) * FrameTime(), 0, 1 );	
	 	
	 	if( self.Primary.PositionMul == 0 ) then
	 	
	 		self.Primary.PositionMode = self.Primary.NextPositionMode;
	 		self.Primary.GoToOriginalPosition = false;
	 	
	 	end
	 		
	 else
	 
		self.Primary.PositionMul = math.Clamp( self.Primary.PositionMul + ( 1 /self.Primary.PositionTime ) * FrameTime(), 0, 1 );			 
	 
	 end
 	 
 	 return pos, ang;
 	 
 end 
   


   
